# @Version        : 1.0
# @Update Time    : 2024/6/16 15:26
# @File           : register.py
# @IDE            : PyCharm
# @Desc           : 插件注册
import os
from contextlib import asynccontextmanager
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from fastapi.staticfiles import StaticFiles

# from starlette.middleware.gzip import GZipMiddleware
from brotli_asgi import BrotliMiddleware

from authx.middlewares import AuthxSessionMiddleware
from src.config import settings
from src.core.exception.exception_handler import refactoring_exception
from .event import db_event
from .middlewares.anti_spider_middleware import AntiSpiderMiddleware
from .middlewares.demo_env_middleware import DemoEnvMiddleware
from .middlewares.link_track_middleware import LinkTrackMiddleware

__all__ = [
    "on_lifespan",
    "register_middleware",
    "register_exception",
    "register_router",
    "register_static",
    "register_system_router",
    "refactoring_exception",
    "register_db",
]

from .middlewares.log_middleware import LogMiddleware

from .middlewares.operation_record_middleware import OperationRecordMiddleware
from ..api.routes import route_list


@asynccontextmanager
async def on_lifespan(app: FastAPI):
    await db_event(app, True)
    yield
    await db_event(app, False)


def register_middleware(app: FastAPI):
    # 注意：先添加的中间件后执行，后添加的先执行，实际注册顺序与执行需求相反

    # 1. Brotli 压缩性能更好 GZip 压缩最先注册（最后执行响应处理）
    app.add_middleware(
        BrotliMiddleware, # type: ignore
    )

    # 2. 操作日志中间件
    app.add_middleware(OperationRecordMiddleware)  # type: ignore

    # 3. 跨域中间件（需保证响应头最后添加）
    if settings.system.CORS_ORIGIN_ENABLE:
        app.add_middleware(
            CORSMiddleware,  # type: ignore
            allow_origins=settings.system.ALLOW_ORIGINS,
            allow_credentials=settings.system.ALLOW_CREDENTIALS,
            allow_methods=settings.system.ALLOW_METHODS,
            allow_headers=settings.system.ALLOW_HEADERS,
        )

    app.add_middleware(AuthxSessionMiddleware)  # type: ignore

    app.add_middleware(LogMiddleware)  # type: ignore

    # 4. 演示环境中间件（在反爬虫之前执行，确保早期进行权限控制）
    if settings.demo.DEMO_ENV:
        app.add_middleware(DemoEnvMiddleware)  # type: ignore

    # 5. 反爬虫中间件
    # app.add_middleware(AntiSpiderMiddleware)  # type: ignore

    # 6. 链路追踪最后注册（最先执行请求处理）
    app.add_middleware(LinkTrackMiddleware)  # type: ignore


def register_exception(app: FastAPI):
    """
    注册异常
    """
    refactoring_exception(app)


def register_static(app: FastAPI):
    """
    挂载静态文件目录
    """
    if not os.path.exists(settings.system.STATIC_PATH):
        # 创建目录
        os.makedirs(settings.system.STATIC_PATH)
    if not os.path.exists(settings.system.ASSETS_PATH):
        os.makedirs(settings.system.ASSETS_PATH)
    # 挂载静态文件, 上传的一些静态图片
    app.mount(
        settings.system.STATIC_URL,
        app=StaticFiles(directory=settings.system.STATIC_PATH),
    )
    # 挂载api文档: swagger_ui, redoc
    app.mount(
        settings.system.ASSETS_URL,
        app=StaticFiles(directory=settings.system.ASSETS_PATH),
    )


def register_router(app: FastAPI):
    """
    注册路由
    """
    for route in route_list:
        app.include_router(route["router"], prefix=route["prefix"], tags=route["tags"])


def register_system_router(app: FastAPI):
    """
    注册系统路由swagger路由
    """
    from ..api.docs import views as docs_views

    docs_views.load_system_routes(app)


# 注册数据库
def register_db(app: FastAPI):
    from src.db.db_database import alchemy

    alchemy.init_app(app)
